<?php
/**
 * This class implements a connection to person search engines
 *
 * @author Thomas Kappel
 * @copyright Copyright (c) 2008
 * @version $Id: Abstract.php 1877 2008-02-19 18:09:30Z tkappel $
 */

class Search {
	/**
	 * @param associative array
	 * @return array of arrays holding fetchable information of all contacts
	 */
	public function execute($person) {
		$socializr = Socializr::getInstance();
    $networks = $socializr->getNetworksWithPossiblyUnknownAccounts($person['person_uri']);
		$name = $person["name"];
	  $yasni = false;
		
	  $hits = array();
		$hit_counter = 0;

    foreach($networks as $network_name) {
      eval('$Network = '.$network_name.'::getInstance();');
      if(!is_a($Network, $network_name)) eval('$Network = new '.$network_name.'();');
      
      $hits[$network_name] = array();
      
      if($Network->supports("search_members") && $Network->connected()) {
        $result = $Network->search($person);
        if(!$result) continue;
        $hits[$network_name] = $result;
        //$hit_counter+=sizeof($hits[$network_name]);
			} else {

        // cut off irrelevant stuff
        if(false === $yasni) $yasni = $this->post_request('http://www.yasni.de/index.php?action=search&update=1&name=' . urlencode($name), array());
    		$start   = stripos($xml,'<form id="update_results">');
        if($start) {
          $xml = substr($xml,$start);
          $start   = stripos($xml,'<table');
          if($start) {
            $xml = substr($xml,$start);
      			// puzzle the required snipplet ;-)
            $start   = stripos($yasni,$network_name);
      			if(!$start) continue;
      			else $start+=strlen($network_name);
      			$snippet = substr($xml,$start);
      			$end     = stripos($snippet,'Mehr Ergebnisse von');
      			if(!$end) continue;
      			$snippet = substr($snippet,0,$end);
      
      			$lines   = explode('</tr>',$snippet);
      			foreach($lines as $line) {
      				$hit = preg_match("%<a (.*)href=\"(.*)\"(.*)>(.*)<.*src=\"(.*)\"%Usi",$line,$matches);
      				if(!$hit) continue;
      				
      				$profile_url = $matches[2];
      				$name        = $matches[4];
      				$depiction   = $matches[5];
      				
              $accountName = substr($profile_url,strrpos($profile_url,"/")+1);
      
      				$hits[$network_name][] = array(
      				  'accountName' => $accountName,
      				  'name'        => $name,
      				  'profile_url' => $profile_url,
      				  'depiction'   => $depiction
      				);
      				//$hit_counter++;
      			}
      		}
        }
			}
  		// throw away accounts to be ignored
  		$filtered_hits = array();
  		foreach($hits as $network_name=>$network_hits) {
  		  foreach($network_hits as $hit) {
    		  $account_uri = $socializr->getAccountUri($hit['accountName'],$network_name);
    		  
          $sparql_account = '
            PREFIX soc: <http://ns.ontowiki.net/plugins/socializr/> .
            ASK WHERE {
              <'.$person['person_uri'].'> soc:holdsAccountNot <'.$account_uri.'>
            }';
          if(false == $socializr->_model->sparqlQuery($sparql_account)) { // account must not be ignored
            $sparql_account = '
              PREFIX foaf: <http://xmlns.com/foaf/0.1/> .
              ASK WHERE {
                <'.$person['person_uri'].'> foaf:holdsAccount <'.$account_uri.'>
              }';
            if(false == $socializr->_model->sparqlQuery($sparql_account)) { // account is still unknown
         		  $filtered_hits[] = $hit;
         		  $hit_counter++;
            }
          }
    		}
    		$hits[$network_name] = $filtered_hits;
      }
    }
		return array("count" => $hit_counter, "hits" => $hits);
	}

	private function create_post_string($method, $params) {
		$params['method'] = $method;
		$params['session_key'] = $this->session_key;
		$params['api_key'] = $this->api_key;
		$params['call_id'] = microtime(true);
		if ($params['call_id'] <= $this->last_call_id) {
			$params['call_id'] = $this->last_call_id + 0.001;
		}
		$this->last_call_id = $params['call_id'];
		$post_params = array();
		foreach ($params as $key => &$val) {
			if (is_array($val)) $val = implode(',', $val);
			$post_params[] = $key.'='.urlencode($val);
		}
		return implode('&', $post_params);
	}

	public function post_request($method, $params) {

		$post_string = $this->create_post_string($method, $params);

		if (function_exists('curl_init')) {
			// Use CURL if installed...
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $method);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($ch, CURLOPT_USERAGENT, 'No Mozilla although open source (curl) ' . phpversion());
			$result = curl_exec($ch);
			curl_close($ch);
		} else {
			// Non-CURL based version...
			$context =
			array('http' =>
			array('method' => 'POST',
                    'header' => 'Content-type: application/x-www-form-urlencoded'."\r\n".
                                'User-Agent: No Mozilla although open source (non-curl) '.phpversion()."\r\n".
                                'Content-length: ' . strlen($post_string),
                    'content' => $post_string));
			$contextid=stream_context_create($context);
			$sock=fopen($method, 'r', false, $contextid);
			if ($sock) {
				$result='';
				while (!feof($sock))
				$result.=fgets($sock, 4096);
				fclose($sock);
			}
		}
		return $result;
	}
}
?>
